<head>
	<title>单处理机调度算法演示</title>
	<script>
		var id = 1;
		var c_time = 0;
		let t_timer;
		
		function killTask(id){
			let task_list = document.getElementById('task_list')
			if(task_list.rows[id].cells[2].innerText>0){
				task_list.rows[id].cells[2].innerText = -1
				task_list.rows[id].cells[3].innerText = '已终止'
			}
		}
		
		function addTask(){
			let task_list = document.getElementById('task_list')
			let new_line = task_list.insertRow()
			new_line.insertCell().innerText = id
			new_line.insertCell().innerText = document.getElementById('t_weight').value
			new_line.insertCell().innerText = document.getElementById('t_time').value
			new_line.insertCell().innerText = "就绪"
			new_line.insertCell().innerHTML = "<button onclick='killTask(" + id + ")'>结束任务</button>"
			id++;
		}
		
		//先来先服务算法
		function execute_fifs(){
			let task_list = document.getElementById('task_list')
			//先来且时间片没耗尽的任务id
			let min_id = -1
			for(let i = 1;i<task_list.rows.length;i++){
				let c_row = task_list.rows[i]
				let r_time = parseInt(c_row.cells[2].innerText)
				if(r_time > 0){
					min_id = i;break;
				}
			}
			//任务全部执行完毕，暂停调度
			if(min_id==-1){
				stopArrangement()
			}
			task_list.rows[min_id].cells[3].innerText = '正在运行'
			task_list.rows[min_id].cells[2].innerText--
			if( task_list.rows[min_id].cells[2].innerText == 0 ){
				task_list.rows[min_id].cells[3].innerText = '结束'
			}
		}
		
		//run_id 最短作业 id
		var run_id = -1;
		//最短作业优先算法
		function execute_sjf(){
			let task_list = document.getElementById('task_list')
			//找到当前的最短作业
			if(run_id==-1){
				let min_r_time = 0x7FFFFFFF
				for(let i = 1;i<task_list.rows.length;i++){
					let c_row = task_list.rows[i]
					let r_time = parseInt(c_row.cells[2].innerText)
					//将某个正在运行但时间片较多的任务挂起
					if(c_row.cells[3].innerText == '正在运行'){
						c_row.cells[3].innerText = '已挂起'
					}
					if(r_time > 0){
						if(r_time < min_r_time){
							//找出剩余时间片最小的任务
							run_id = i;
							min_r_time = r_time;
						}
					}
				}
			}
			//当前没有可运行的任务
			if(run_id==-1){
				stopArrangement()
			}
			
			task_list.rows[run_id].cells[3].innerText = '正在运行'
			task_list.rows[run_id].cells[2].innerText--
			if( task_list.rows[run_id].cells[2].innerText == 0 ){
				task_list.rows[run_id].cells[3].innerText = '结束'
				//重新寻找下一个任务
				run_id = -1;
			}
		}
		
		//最短剩余时间优先算法
		function execute_srtf(){
			let task_list = document.getElementById('task_list')
			//时间片最小的任务id
			let min_id = -1
			let min_r_time = 0x7FFFFFFF
			for(let i = 1;i<task_list.rows.length;i++){
				let c_row = task_list.rows[i]
				let r_time = parseInt(c_row.cells[2].innerText)
				//将某个正在运行但时间片较多的任务挂起
				if(c_row.cells[3].innerText == '正在运行'){
					c_row.cells[3].innerText = '已挂起'
				}
				if(r_time > 0){
					if(r_time < min_r_time){
						//找出剩余时间片最小的任务
						min_id = i;
						min_r_time = r_time;
					}
				}
			}
			//任务全部执行完毕，暂停调度
			if(min_id==-1){
				stopArrangement()
			}
			task_list.rows[min_id].cells[3].innerText = '正在运行'
			task_list.rows[min_id].cells[2].innerText--
			if( task_list.rows[min_id].cells[2].innerText == 0 ){
				task_list.rows[min_id].cells[3].innerText = '结束'
			}
		}
		
		function Arrangement(algorthim){
			c_time++;
			document.getElementById('status').innerText = '调度算法正在运行，当前已用时' + c_time + ' s'
			getAlgorthim(algorthim)()
		}
		
		function beginArrangement(){
			let algorthim = document.getElementById('sele_alg').selectedOptions[0].value
			document.getElementById('btn_add_task').disabled = true
			document.getElementById('sele_alg').disabled = true
			t_timer = setInterval(()=>{Arrangement(algorthim)},1000)
		}
		
		function getAlgorthim(algorthim){
			if(algorthim=='execute_fifs'){
				return execute_fifs
			}
			if(algorthim=='execute_sjf'){
				return execute_sjf
			}
			if(algorthim=='execute_srtf'){
				return execute_srtf
			}
		}
		
		function stopArrangement(){
			document.getElementById('status').innerText = '调度算法暂停，当前已用时' + c_time + ' s'
			document.getElementById('btn_add_task').disabled = false
			document.getElementById('sele_alg').disabled = false
			clearInterval(t_timer)
		}
		
	</script>
</head>

<body>
	<form>
		任务权重： <input id='t_weight' type='number' value='1'><br>
		执行时间： <input id='t_time' type='number' value='10'><br>
	</form>
	<button id='btn_add_task' onclick='addTask()'>添加任务</button>
	<button onclick="window.location.href=''">重置</button><br><br>
	算法：
	<select id="sele_alg">
		<option value='execute_fifs' selected>先来先服务</option>
		<option value='execute_sjf'>最短作业优先</option>
		<option value='execute_srtf'>最短剩余时间优先</option>
	</select>
	<button onclick='beginArrangement()'>运行调度</button>
	<button onclick='stopArrangement()'>暂停调度</button>
	<p id='status'>点击运行调度以开始算法</p>
	<table id='task_list'>
		<tr>
			<th>任务id</th>
			<th>权重</th>
			<th>剩余时间</th>
			<th>状态</th>
			<th>操作</th>
		</tr>
	</table>
		
</body>